package com.itjin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itjin.mapper.PostMapper;
import com.itjin.mapper.UserMapper;
import com.itjin.mapper.PostLikeMapper;
import com.itjin.mapper.PostCommentMapper;
import com.itjin.mapper.PostCollectMapper;
import com.itjin.mapper.PostReportMapper;
import com.itjin.model.domain.entity.Post;
import com.itjin.model.domain.entity.User;
import com.itjin.model.domain.entity.PostLike;
import com.itjin.model.domain.entity.PostComment;
import com.itjin.model.domain.entity.PostCollect;
import com.itjin.model.domain.entity.PostReport;
import com.itjin.model.domain.vo.GetPostListVO;
import com.itjin.model.domain.vo.PostLikeVO;
import com.itjin.model.domain.vo.PostDetailVO;
import com.itjin.model.domain.dto.CreatePostDTO;
import com.itjin.model.domain.vo.CommentVO;
import com.itjin.model.domain.dto.CreateCommentDTO;
import com.itjin.model.domain.vo.PostCollectVO;
import com.itjin.model.domain.dto.PostReportDTO;
import com.itjin.model.domain.vo.ReportedPostVO;
import com.itjin.model.domain.dto.IncreasePostHeatDTO;
import com.itjin.model.domain.vo.PostHeatVO;
import com.itjin.model.domain.dto.PostListQueryDTO;
import com.itjin.contant.PostSortType;
import com.itjin.service.PostService;
import com.itjin.service.MessageService;
import com.itjin.service.ContentAuditService;
import com.itjin.model.domain.dto.SendMessageDTO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Collections;
import java.util.HashSet;

@Service
@Slf4j
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {

  @Resource
  private UserMapper userMapper;

  @Resource
  private PostMapper postMapper;

  @Resource
  private PostLikeMapper postLikeMapper;

  @Resource
  private PostCommentMapper commentMapper;

  @Resource
  private PostCollectMapper postCollectMapper;

  @Resource
  private PostReportMapper postReportMapper;

  @Resource
  private MessageService messageService;

  @Resource
  private ObjectMapper objectMapper;

  @Resource
  @Lazy
  private ContentAuditService contentAuditService;

  @Override
  @Transactional
  public PostLikeVO likePost(Integer postId, Integer userId) {
    try {
      // 1. 参数校验
      if (postId == null || postId <= 0) {
        throw new IllegalArgumentException("帖子ID不合法");
      }
      if (userId == null || userId <= 0) {
        throw new IllegalArgumentException("用户ID不合法");
      }

      // 2. 检查帖子是否存在
      Post post = postMapper.selectById(postId);
      if (post == null || post.getPostStatus() != 3) {
        throw new IllegalArgumentException("帖子不存在或已删除");
      }

      // 3. 获取当前点赞状态
      QueryWrapper<PostLike> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("postId", postId)
          .eq("userId", userId);
      PostLike existingLike = postLikeMapper.selectOne(queryWrapper);

      boolean isNewLike = false;
      if (existingLike == null) {
        // 新点赞
        isNewLike = true;
      } else if (existingLike.getStatus() == 0) {
        // 重新点赞
        isNewLike = true;
      } else {
        // 取消点赞
        isNewLike = false;
      }

      // 4. 执行点赞/取消点赞操作
      int rows = postLikeMapper.toggleLike(postId, userId);

      // 5. 更新帖子点赞数
      if (rows > 0) {
        // 重新查询点赞状态
        PostLike updatedLike = postLikeMapper.selectOne(queryWrapper);

        // 更新帖子点赞数
        Post updatePost = new Post();
        updatePost.setId(postId);

        if (isNewLike) {
          // 点赞数+1
          updatePost.setLikesCount(post.getLikesCount() + 1);
          // 更新帖子作者的获赞数+1
          postLikeMapper.updateUserPraised(post.getAuthorId(), 1);
        } else {
          // 点赞数-1
          updatePost.setLikesCount(Math.max(0, post.getLikesCount() - 1));
          // 更新帖子作者的获赞数-1
          postLikeMapper.updateUserPraised(post.getAuthorId(), -1);
        }

        postMapper.updateById(updatePost);

        // 6. 构建返回对象
        return PostLikeVO.builder()
            .id(updatedLike != null ? updatedLike.getId() : null)
            .postId(postId)
            .userId(userId)
            .createTime(updatedLike != null ? updatedLike.getCreateTime() : null)
            .status(updatedLike != null ? updatedLike.getStatus() : 0)
            .totalLikes(updatePost.getLikesCount())
            .build();
      } else {
        throw new RuntimeException("点赞操作失败");
      }
    } catch (Exception e) {
      log.error("点赞失败", e);
      throw new RuntimeException("点赞失败: " + e.getMessage());
    }
  }

  @Override
  public PostDetailVO getPostDetail(Integer postId) {
    // 1. 参数校验
    if (postId == null || postId <= 0) {
      throw new RuntimeException("帖子ID不合法");
    }

    // 2. 查询帖子
    Post post = this.getById(postId);
    if (post == null) {
      throw new RuntimeException("帖子不存在");
    }

    try {
      // 3. 查询作者信息
      User author = userMapper.selectById(post.getAuthorId());

      // 4. 查询评论列表
      List<PostComment> comments = commentMapper.selectList(
          new QueryWrapper<PostComment>()
              .eq("postId", postId)
              .eq("status", 1)
              .eq("isDeleted", 0)
              .isNull("parentCommentId") // 只查询主评论
              .orderByDesc("createTime"));

      // 5. 构建评论VO列表
      List<CommentVO> commentVOList = new ArrayList<>();
      for (PostComment comment : comments) {
        // 查询评论作者信息
        User commentUser = userMapper.selectById(comment.getUserId());

        // 查询回复列表
        List<PostComment> replies = commentMapper.selectList(
            new QueryWrapper<PostComment>()
                .eq("parentCommentId", comment.getId())
                .eq("status", 1)
                .eq("isDeleted", 0)
                .orderByAsc("createTime"));

        // 构建回复VO列表
        List<CommentVO> replyVOList = new ArrayList<>();
        for (PostComment reply : replies) {
          User replyUser = userMapper.selectById(reply.getUserId());
          replyVOList.add(CommentVO.builder()
              .id(reply.getId())
              .userId(reply.getUserId())
              .username(reply.getIsAnonymity() == 1 ? "匿名用户" : (replyUser != null ? replyUser.getUsername() : "未知用户"))
              .userAvatar(reply.getIsAnonymity() == 1 ? null : (replyUser != null ? replyUser.getAvatar() : null))
              .content(reply.getCommentText())
              .isAnonymity(reply.getIsAnonymity())
              .createTime(reply.getCreateTime())
              .replyCount(reply.getReplyCount())
              .build());
        }

        // 构建评论VO
        commentVOList.add(CommentVO.builder()
            .id(comment.getId())
            .userId(comment.getUserId())
            .username(
                comment.getIsAnonymity() == 1 ? "匿名用户" : (commentUser != null ? commentUser.getUsername() : "未知用户"))
            .userAvatar(comment.getIsAnonymity() == 1 ? null : (commentUser != null ? commentUser.getAvatar() : null))
            .content(comment.getCommentText())
            .isAnonymity(comment.getIsAnonymity())
            .createTime(comment.getCreateTime())
            .replyCount(comment.getReplyCount())
            .replies(replyVOList)
            .build());
      }

      // 6. 增加浏览量
      Post updatePost = new Post();
      updatePost.setId(postId);
      updatePost.setViewsCount(post.getViewsCount() + 1);
      this.updateById(updatePost);

      // 7. 构建返回对象
      PostDetailVO postDetailVO = PostDetailVO.builder()
          .id(post.getId())
          .authorId(post.getAuthorId())
          .title(post.getTitle())
          .authorName(author != null ? author.getUsername() : "未知用户")
          .authorAvatar(author != null ? author.getAvatar() : null)
          .content(post.getContent())
          .image1(post.getImage1())
          .image2(post.getImage2())
          .image3(post.getImage3())
          .image4(post.getImage4())
          .image5(post.getImage5())
          .image6(post.getImage6())
          .image7(post.getImage7())
          .image8(post.getImage8())
          .image9(post.getImage9())
          .isAnonymous(post.getIsAnonymous())
          .type(post.getType())
          .createTime(post.getCreateTime())
          .updateTime(post.getUpdateTime())
          .postStatus(post.getPostStatus())
          .viewsCount(post.getViewsCount() + 1) // 返回更新后的浏览量
          .commentsCount(post.getCommentsCount())
          .likesCount(post.getLikesCount())
          .collectsCount(post.getCollectsCount())
          .comments(commentVOList)
          .build();

      // 处理 tags
      if (post.getTags() != null && !post.getTags().isEmpty()) {
        try {
          List<String> tagsList = objectMapper.readValue(post.getTags(), new TypeReference<List<String>>() {
          });
          postDetailVO.setTags(tagsList);
        } catch (JsonProcessingException e) {
          log.error("反序列化帖子标签失败, postId: {}", postId, e);
          postDetailVO.setTags(Collections.emptyList()); // 出错时返回空列表
        }
      } else {
        postDetailVO.setTags(Collections.emptyList());
      }

      return postDetailVO;

    } catch (Exception e) {
      log.error("获取帖子详情失败", e);
      throw new RuntimeException("获取帖子详情失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public Integer createPost(CreatePostDTO createPostDTO) {
    // 1. 参数校验
    if (createPostDTO == null) {
      throw new RuntimeException("参数不能为空");
    }
    if (createPostDTO.getAuthorId() == null || createPostDTO.getAuthorId() <= 0) {
      throw new RuntimeException("作者ID不合法");
    }
    if (createPostDTO.getContent() == null || createPostDTO.getContent().trim().isEmpty()) {
      throw new RuntimeException("帖子内容不能为空");
    }

    // 2. 检查作者是否存在
    User author = userMapper.selectById(createPostDTO.getAuthorId());
    if (author == null) {
      throw new RuntimeException("作者不存在");
    }

    try {
      // 3. 构建帖子对象
      Post post = new Post();
      post.setAuthorId(createPostDTO.getAuthorId());
      post.setTitle(createPostDTO.getTitle());
      post.setContent(createPostDTO.getContent());
      post.setImage1(createPostDTO.getImage1());
      post.setImage2(createPostDTO.getImage2());
      post.setImage3(createPostDTO.getImage3());
      post.setImage4(createPostDTO.getImage4());
      post.setImage5(createPostDTO.getImage5());
      post.setImage6(createPostDTO.getImage6());
      post.setImage7(createPostDTO.getImage7());
      post.setImage8(createPostDTO.getImage8());
      post.setImage9(createPostDTO.getImage9());
      post.setIsAnonymous(createPostDTO.getIsAnonymous());
      post.setType(createPostDTO.getType());

      // 处理 tags
      if (createPostDTO.getTags() != null && !createPostDTO.getTags().isEmpty()) {
        try {
          post.setTags(objectMapper.writeValueAsString(createPostDTO.getTags()));
        } catch (JsonProcessingException e) {
          log.error("序列化帖子标签失败", e);
          throw new RuntimeException("处理帖子标签失败");
        }
      }

      post.setPostStatus(4); // 设置为AI审查中状态
      post.setViewsCount(0);
      post.setCommentsCount(0);
      post.setLikesCount(0);
      post.setCollectsCount(0);

      // 4. 保存帖子
      boolean saved = this.save(post);
      if (!saved) {
        throw new RuntimeException("发布帖子失败");
      }

      // 5. 发送到内容审核队列
      try {
        boolean auditSent = contentAuditService.sendPostForAudit(post);
        if (auditSent) {
          log.info("帖子已发送到审核队列: postId={}", post.getId());
        } else {
          log.warn("发送帖子到审核队列失败，将保持待审核状态: postId={}", post.getId());
        }
      } catch (Exception e) {
        log.error("发送帖子到审核队列异常: postId={}, error={}", post.getId(), e.getMessage());
        // 不抛出异常，让帖子保持待审核状态，可以后续人工处理
      }

      // 6. 更新用户的发帖数
      User updateUser = new User();
      updateUser.setId(createPostDTO.getAuthorId());
      updateUser.setMyPublish(author.getMyPublish() + 1);
      boolean userUpdated = userMapper.updateById(updateUser) > 0;
      if (!userUpdated) {
        throw new RuntimeException("更新用户发帖数失败");
      }

      // 7. 返回帖子ID
      return post.getId();

    } catch (Exception e) {
      log.error("发布帖子失败", e);
      throw new RuntimeException("发布帖子失败: " + e.getMessage());
    }
  }

  @Override
  public CommentVO createComment(CreateCommentDTO createCommentDTO) {
    // 1. 参数校验
    if (createCommentDTO == null) {
      throw new RuntimeException("参数不能为空");
    }
    if (createCommentDTO.getPostId() == null || createCommentDTO.getPostId() <= 0) {
      throw new RuntimeException("帖子ID不合法");
    }
    if (createCommentDTO.getUserId() == null || createCommentDTO.getUserId() <= 0) {
      throw new RuntimeException("用户ID不合法");
    }
    if (createCommentDTO.getCommentText() == null || createCommentDTO.getCommentText().trim().isEmpty()) {
      throw new RuntimeException("评论内容不能为空");
    }

    // 2. 检查帖子是否存在
    Post post = this.getById(createCommentDTO.getPostId());
    if (post == null) {
      throw new RuntimeException("帖子不存在");
    }

    // 3. 检查用户是否存在
    User user = userMapper.selectById(createCommentDTO.getUserId());
    if (user == null) {
      throw new RuntimeException("用户不存在");
    }

    try {
      // 4. 如果是回复评论，检查父评论是否存在
      if (createCommentDTO.getParentCommentId() != null) {
        PostComment parentComment = commentMapper.selectById(createCommentDTO.getParentCommentId());
        if (parentComment == null) {
          throw new RuntimeException("回复的评论不存在");
        }
        // 更新父评论的回复数
        PostComment updateParent = new PostComment();
        updateParent.setId(parentComment.getId());
        updateParent.setReplyCount(parentComment.getReplyCount() + 1);
        commentMapper.updateById(updateParent);
      }

      // 5. 创建评论
      PostComment comment = new PostComment();
      comment.setPostId(createCommentDTO.getPostId());
      comment.setUserId(createCommentDTO.getUserId());
      comment.setCommentText(createCommentDTO.getCommentText());
      comment.setIsAnonymity(createCommentDTO.getIsAnonymity());
      comment.setParentCommentId(createCommentDTO.getParentCommentId());
      comment.setStatus(1);
      comment.setIsDeleted(0);
      comment.setReplyCount(0);

      // 6. 保存评论
      boolean saved = commentMapper.insert(comment) > 0;
      if (!saved) {
        throw new RuntimeException("发表评论失败");
      }

      // 7. 更新帖子评论数
      Post updatePost = new Post();
      updatePost.setId(post.getId());
      updatePost.setCommentsCount(post.getCommentsCount() + 1);
      this.updateById(updatePost);

      // 8. 构建返回对象
      return CommentVO.builder()
          .id(comment.getId())
          .userId(comment.getUserId())
          .username(comment.getIsAnonymity() == 1 ? "匿名用户" : user.getUsername())
          .userAvatar(comment.getIsAnonymity() == 1 ? null : user.getAvatar())
          .content(comment.getCommentText())
          .isAnonymity(comment.getIsAnonymity())
          .createTime(comment.getCreateTime())
          .replyCount(0)
          .replies(new ArrayList<>())
          .build();

    } catch (Exception e) {
      log.error("发表评论失败", e);
      throw new RuntimeException("发表评论失败: " + e.getMessage());
    }
  }

  @Override
  public boolean deleteComment(Integer commentId, Integer userId) {
    // 1. 参数校验
    if (commentId == null || commentId <= 0) {
      throw new RuntimeException("评论ID不合法");
    }
    if (userId == null || userId <= 0) {
      throw new RuntimeException("用户ID不合法");
    }

    try {
      // 2. 查询评论是否存在
      PostComment comment = commentMapper.selectById(commentId);
      if (comment == null || comment.getIsDeleted() == 1) {
        throw new RuntimeException("评论不存在");
      }

      // 3. 查询帖子信息
      Post post = this.getById(comment.getPostId());
      if (post == null) {
        throw new RuntimeException("帖子不存在");
      }

      // 4. 验证权限（评论作者或帖子作者可以删除评论）
      boolean isCommentAuthor = comment.getUserId().equals(userId);
      boolean isPostAuthor = post.getAuthorId().equals(userId);
      if (!isCommentAuthor && !isPostAuthor) {
        throw new RuntimeException("无权删除该评论");
      }

      // 5. 如果是主评论，需要同时删除所有回复
      if (comment.getParentCommentId() == null) {
        // 更新所有回复的状态为已删除
        PostComment updateReplies = new PostComment();
        updateReplies.setIsDeleted(1);
        commentMapper.update(updateReplies,
            new QueryWrapper<PostComment>()
                .eq("parentCommentId", commentId));
      } else {
        // 如果是回复，需要更新父评论的回复数
        PostComment parentComment = commentMapper.selectById(comment.getParentCommentId());
        if (parentComment != null && parentComment.getIsDeleted() == 0) {
          PostComment updateParent = new PostComment();
          updateParent.setId(parentComment.getId());
          updateParent.setReplyCount(parentComment.getReplyCount() - 1);
          commentMapper.updateById(updateParent);
        }
      }

      // 6. 标记评论为已删除
      PostComment updateComment = new PostComment();
      updateComment.setId(commentId);
      updateComment.setIsDeleted(1);
      boolean updated = commentMapper.updateById(updateComment) > 0;

      if (updated) {
        // 7. 更新帖子评论数
        Post updatePost = new Post();
        updatePost.setId(post.getId());
        updatePost.setCommentsCount(post.getCommentsCount() - 1);
        this.updateById(updatePost);
      }

      return updated;

    } catch (Exception e) {
      log.error("删除评论失败", e);
      throw new RuntimeException("删除评论失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public PostCollectVO collectPost(Integer postId, Integer userId) {
    try {
      // 1. 参数校验
      if (postId == null || postId <= 0) {
        throw new IllegalArgumentException("帖子ID不合法");
      }
      if (userId == null || userId <= 0) {
        throw new IllegalArgumentException("用户ID不合法");
      }

      // 2. 检查帖子是否存在
      Post post = postMapper.selectById(postId);
      if (post == null || post.getPostStatus() != 3) {
        throw new IllegalArgumentException("帖子不存在或已删除");
      }

      // 3. 获取当前收藏状态
      QueryWrapper<PostCollect> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("postId", postId)
          .eq("userId", userId);
      PostCollect existingCollect = postCollectMapper.selectOne(queryWrapper);

      boolean isNewCollect = false;
      if (existingCollect == null) {
        // 新收藏
        isNewCollect = true;
      } else if (existingCollect.getStatus() == 0) {
        // 重新收藏
        isNewCollect = true;
      } else {
        // 取消收藏
        isNewCollect = false;
      }

      // 4. 执行收藏/取消收藏操作
      int rows = postCollectMapper.toggleCollect(postId, userId);

      // 5. 更新帖子收藏数和用户收藏数
      if (rows > 0) {
        // 重新查询收藏状态
        PostCollect updatedCollect = postCollectMapper.selectOne(queryWrapper);

        // 更新帖子收藏数
        Post updatePost = new Post();
        updatePost.setId(postId);

        if (isNewCollect) {
          // 收藏数+1
          updatePost.setCollectsCount(post.getCollectsCount() + 1);
          // 更新用户的收藏数+1
          postCollectMapper.updateUserCollection(userId, 1);
        } else {
          // 收藏数-1
          updatePost.setCollectsCount(Math.max(0, post.getCollectsCount() - 1));
          // 更新用户的收藏数-1
          postCollectMapper.updateUserCollection(userId, -1);
        }

        postMapper.updateById(updatePost);

        // 6. 构建返回对象
        return PostCollectVO.builder()
            .id(updatedCollect != null ? updatedCollect.getId() : null)
            .postId(postId)
            .userId(userId)
            .createTime(updatedCollect != null ? updatedCollect.getCreateTime() : null)
            .status(updatedCollect != null ? updatedCollect.getStatus() : 0)
            .totalCollects(updatePost.getCollectsCount())
            .build();
      } else {
        throw new RuntimeException("收藏操作失败");
      }
    } catch (Exception e) {
      log.error("收藏失败", e);
      throw new RuntimeException("收藏失败: " + e.getMessage());
    }
  }

  @Override
  public List<GetPostListVO> getPostListWithSort(PostListQueryDTO queryParam) {

    // 1. 参数校验
    if (queryParam == null) {
      queryParam = new PostListQueryDTO(); // 使用默认参数
    }
    if (!queryParam.isValid()) {
      throw new RuntimeException("查询参数不合法");
    }

    // 2. 构建查询条件
    QueryWrapper<Post> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("postStatus", 3); // 只查询已发布的帖子

    // 添加类型过滤条件
    if (queryParam.getType() != null) {
      queryWrapper.eq("type", queryParam.getType());
    }

    // 3. 根据排序类型设置排序条件
    PostSortType sortType = PostSortType.getByCode(queryParam.getSortType());
    switch (sortType) {
      case TIME:
        queryWrapper.orderByDesc("createTime");
        break;
      case LIKES:
        queryWrapper.orderByDesc("likesCount").orderByDesc("createTime"); // 点赞数相同时按时间排序
        break;
      case HEAT:
      default:
        // 热度排序：先按热度值降序，热度相同时按创建时间降序
        queryWrapper.orderByDesc("heatCount").orderByDesc("createTime");
        break;
    }

    // 4. 查询帖子列表
    List<Post> posts = this.list(queryWrapper);
    if (posts == null || posts.isEmpty()) {
      return new ArrayList<>();
    }

    // 5. 获取所有作者ID
    Set<Integer> authorIds = posts.stream()
        .map(Post::getAuthorId)
        .collect(Collectors.toSet());

    // 6. 批量查询作者信息
    Map<Integer, User> userMap = userMapper.selectBatchIds(authorIds).stream()
        .collect(Collectors.toMap(User::getId, user -> user));

    // 7. 转换为VO对象
    return posts.stream().map(post -> {
      User author = userMap.get(post.getAuthorId());
      String authorName = author != null ? author.getUsername() : "未知用户";
      String authorAvatar = author != null ? author.getAvatar() : "";

      GetPostListVO postVO = GetPostListVO.builder()
          .id(post.getId())
          .authorId(post.getAuthorId())
          .authorName(post.getIsAnonymous() == 1 ? "匿名用户" : authorName)
          .authorAvatar(post.getIsAnonymous() == 1 ? "" : authorAvatar)
          .title(post.getTitle())
          .content(post.getContent())
          .image1(post.getImage1())
          .image2(post.getImage2())
          .image3(post.getImage3())
          .image4(post.getImage4())
          .image5(post.getImage5())
          .image6(post.getImage6())
          .image7(post.getImage7())
          .image8(post.getImage8())
          .image9(post.getImage9())
          .type(post.getType())
          .isAnonymous(post.getIsAnonymous())
          .createTime(post.getCreateTime())
          .updateTime(post.getUpdateTime())
          .viewsCount(post.getViewsCount())
          .commentsCount(post.getCommentsCount())
          .likesCount(post.getLikesCount())
          .collectsCount(post.getCollectsCount())
          .build();

      // 处理 tags
      if (post.getTags() != null && !post.getTags().isEmpty()) {
        try {
          List<String> tagsList = objectMapper.readValue(post.getTags(), new TypeReference<List<String>>() {
          });
          postVO.setTags(tagsList);
        } catch (JsonProcessingException e) {
          log.error("反序列化帖子列表标签失败, postId: {}", post.getId(), e);
          postVO.setTags(Collections.emptyList()); // 出错时返回空列表
        }
      } else {
        postVO.setTags(Collections.emptyList());
      }

      return postVO;
    }).collect(Collectors.toList());
  }

  @Override
  @Transactional
  public boolean deletePost(Integer postId, Integer userId) {
    // 1. 参数校验
    if (postId == null || postId <= 0) {
      throw new IllegalArgumentException("帖子ID不合法");
    }
    if (userId == null || userId <= 0) {
      throw new IllegalArgumentException("用户ID不合法");
    }

    // 2. 查询帖子信息
    Post post = this.getById(postId);
    if (post == null) {
      throw new IllegalArgumentException("帖子不存在");
    }

    // 3. 验证权限（只有作者和管理员可以删除）
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new IllegalArgumentException("用户不存在");
    }

    if (!post.getAuthorId().equals(userId) && !user.getUserRole().equals(0)) {
      throw new IllegalArgumentException("没有权限删除该帖子");
    }

    try {
      // 4. 更新帖子状态为已删除
      Post updatePost = new Post();
      updatePost.setId(postId);
      updatePost.setPostStatus(2); // 2表示已删除
      boolean success = this.updateById(updatePost);

      if (success) {
        // 5. 更新作者的发帖数
        User author = userMapper.selectById(post.getAuthorId());
        if (author != null && author.getMyPublish() > 0) {
          User updateAuthor = new User();
          updateAuthor.setId(author.getId());
          updateAuthor.setMyPublish(author.getMyPublish() - 1);
          userMapper.updateById(updateAuthor);
        }
      }

      return success;
    } catch (Exception e) {
      log.error("删除帖子失败", e);
      throw new RuntimeException("删除帖子失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public boolean reportPost(PostReportDTO reportDTO) {
    // 1. 参数校验
    if (reportDTO.getPostId() == null || reportDTO.getPostId() <= 0) {
      throw new IllegalArgumentException("帖子ID不合法");
    }
    if (reportDTO.getUserId() == null || reportDTO.getUserId() <= 0) {
      throw new IllegalArgumentException("用户ID不合法");
    }
    if (reportDTO.getReason() == null || reportDTO.getReason().trim().isEmpty()) {
      throw new IllegalArgumentException("举报原因不能为空");
    }

    try {
      // 2. 检查帖子是否存在
      Post post = this.getById(reportDTO.getPostId());
      if (post == null) {
        throw new IllegalArgumentException("帖子不存在");
      }

      // 3. 检查用户是否存在
      User user = userMapper.selectById(reportDTO.getUserId());
      if (user == null) {
        throw new IllegalArgumentException("用户不存在");
      }

      // 4. 检查是否已经举报过
      QueryWrapper<PostReport> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("postId", reportDTO.getPostId())
          .eq("userId", reportDTO.getUserId());
      PostReport existingReport = postReportMapper.selectOne(queryWrapper);

      if (existingReport != null) {
        throw new IllegalArgumentException("您已经举报过该帖子");
      }

      // 5. 创建举报记录
      PostReport report = new PostReport();
      report.setPostId(reportDTO.getPostId());
      report.setUserId(reportDTO.getUserId());
      report.setReason(reportDTO.getReason().trim());
      report.setStatus(1);
      report.setCreateTime(new Date());

      int rows = postReportMapper.insert(report);
      if (rows <= 0) {
        throw new RuntimeException("创建举报记录失败");
      }

      // 6. 更新帖子的举报状态和举报次数
      Post updatePost = new Post();
      updatePost.setId(reportDTO.getPostId());
      updatePost.setIsReport(1);
      Integer currentReportCount = post.getReportCount();
      updatePost.setReportCount(currentReportCount == null ? 1 : currentReportCount + 1);

      boolean updated = this.updateById(updatePost);
      if (!updated) {
        throw new RuntimeException("更新帖子举报状态失败");
      }

      return true;
    } catch (Exception e) {
      log.error("举报帖子失败", e);
      throw new RuntimeException("举报帖子失败: " + e.getMessage());
    }
  }

  @Override
  public List<ReportedPostVO> getReportedPosts() {
    try {
      // 1. 查询所有被举报的帖子
      List<Post> reportedPosts = this.list(
          new QueryWrapper<Post>()
              .eq("isReport", 1)
              .eq("postStatus", 3)
              .orderByDesc("reportCount"));

      if (reportedPosts.isEmpty()) {
        return Collections.emptyList();
      }

      // 2. 获取所有帖子ID
      List<Integer> postIds = reportedPosts.stream()
          .map(Post::getId)
          .collect(Collectors.toList());

      // 3. 查询这些帖子的举报记录
      List<PostReport> reports = postReportMapper.selectList(
          new QueryWrapper<PostReport>()
              .in("postId", postIds)
              .orderByDesc("createTime"));

      // 4. 获取所有相关用户ID（包括作者和举报者）
      Set<Integer> userIds = new HashSet<>();
      reportedPosts.forEach(post -> userIds.add(post.getAuthorId()));
      reports.forEach(report -> userIds.add(report.getUserId()));

      // 5. 批量查询用户信息
      Map<Integer, User> userMap = userMapper.selectBatchIds(userIds)
          .stream()
          .collect(Collectors.toMap(User::getId, user -> user));

      // 6. 按帖子ID分组举报信息
      Map<Integer, List<PostReport>> reportMap = reports.stream()
          .collect(Collectors.groupingBy(PostReport::getPostId));

      // 7. 构建返回结果
      return reportedPosts.stream().map(post -> {
        User author = userMap.get(post.getAuthorId());
        List<PostReport> postReports = reportMap.get(post.getId());

        List<ReportedPostVO.ReportInfo> reportInfos = postReports.stream()
            .map(report -> {
              User reporter = userMap.get(report.getUserId());
              return ReportedPostVO.ReportInfo.builder()
                  .reportId(report.getId())
                  .reporterId(reporter.getId())
                  .reporterName(reporter.getUsername())
                  .reporterAvatar(reporter.getAvatar())
                  .reason(report.getReason())
                  .reportTime(report.getCreateTime())
                  .status(report.getStatus())
                  .build();
            })
            .collect(Collectors.toList());

        return ReportedPostVO.builder()
            .postId(post.getId())
            .title(post.getTitle())
            .content(post.getContent())
            .authorId(post.getAuthorId())
            .authorName(author != null ? author.getUsername() : "未知用户")
            .authorAvatar(author != null ? author.getAvatar() : null)
            .createTime(post.getCreateTime())
            .reportCount(post.getReportCount())
            .reports(reportInfos)
            .build();
      }).collect(Collectors.toList());
    } catch (Exception e) {
      log.error("获取被举报帖子列表失败", e);
      throw new RuntimeException("获取被举报帖子列表失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public boolean approveReport(Integer reportId, String handleResult) {
    try {
      // 1. 参数校验
      if (reportId == null || reportId <= 0) {
        throw new IllegalArgumentException("举报ID不合法");
      }
      if (handleResult == null || handleResult.trim().isEmpty()) {
        throw new IllegalArgumentException("处理结果说明不能为空");
      }

      // 2. 查询举报记录
      PostReport report = postReportMapper.selectById(reportId);
      if (report == null) {
        throw new IllegalArgumentException("举报记录不存在");
      }
      if (report.getStatus() == 0) {
        throw new IllegalArgumentException("该举报已经处理过了");
      }

      // 3. 获取帖子ID，并处理该帖子的所有未处理举报
      Integer postId = report.getPostId();
      PostReport batchUpdate = new PostReport();
      batchUpdate.setStatus(0); // 0表示已处理
      batchUpdate.setHandleTime(new Date());
      batchUpdate.setHandleResult(handleResult.trim());

      postReportMapper.update(batchUpdate,
          new QueryWrapper<PostReport>()
              .eq("postId", postId)
              .eq("status", 1));

      // 4. 更新帖子状态为未被举报
      Post updatePost = new Post();
      updatePost.setId(postId);
      updatePost.setIsReport(0); // 设置为未被举报状态
      boolean updated = this.updateById(updatePost);
      if (!updated) {
        throw new RuntimeException("更新帖子状态失败");
      }

      return true;
    } catch (Exception e) {
      log.error("处理举报失败", e);
      throw new RuntimeException("处理举报失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public boolean rejectAndDeletePost(Integer reportId, String handleResult) {
    try {
      // 1. 参数校验
      if (reportId == null || reportId <= 0) {
        throw new IllegalArgumentException("举报ID不合法");
      }
      if (handleResult == null || handleResult.trim().isEmpty()) {
        throw new IllegalArgumentException("处理结果说明不能为空");
      }

      // 2. 查询举报记录
      PostReport report = postReportMapper.selectById(reportId);
      if (report == null) {
        throw new IllegalArgumentException("举报记录不存在");
      }
      if (report.getStatus() == 0) {
        throw new IllegalArgumentException("该举报已经处理过了");
      }

      // 3. 获取帖子ID，并处理该帖子的所有未处理举报
      Integer postId = report.getPostId();
      PostReport batchUpdate = new PostReport();
      batchUpdate.setStatus(0); // 0表示已处理
      batchUpdate.setHandleTime(new Date());
      batchUpdate.setHandleResult("帖子已删除: " + handleResult.trim());

      postReportMapper.update(batchUpdate,
          new QueryWrapper<PostReport>()
              .eq("postId", postId)
              .eq("status", 1));

      // 4. 将帖子标记为删除状态，同时更新举报相关状态
      Post updatePost = new Post();
      updatePost.setId(postId);
      updatePost.setPostStatus(2); // 2表示已删除
      updatePost.setIsReport(1); // 保持举报状态
      updatePost.setUpdateTime(new Date()); // 更新修改时间

      // 使用QueryWrapper确保更新成功
      boolean updated = this.update(updatePost,
          new QueryWrapper<Post>()
              .eq("id", postId)
              .ne("postStatus", 2)); // 只有在帖子未被删除的情况下才更新

      if (!updated) {
        throw new RuntimeException("删除帖子失败，该帖子可能已被删除");
      }

      // 5. 给作者发送消息通知
      Post originalPost = this.getById(postId);
      if (originalPost != null) {
        // 获取作者信息
        Integer authorId = originalPost.getAuthorId();

        // 构建消息内容
        String messageContent = String.format(
            "您的帖子《%s》因违规已被删除。处理原因：%s",
            originalPost.getTitle(),
            handleResult.trim());

        // 创建消息DTO
        SendMessageDTO messageDTO = new SendMessageDTO();
        messageDTO.setReceiverId(authorId);
        messageDTO.setContent(messageContent);
        messageDTO.setMessageType(1); // 系统消息类型

        // 发送消息
        messageService.sendMessage(666, messageDTO); // 使用管理员ID 666

        // 更新作者的发帖数
        User author = userMapper.selectById(authorId);
        if (author != null && author.getMyPublish() > 0) {
          User updateAuthor = new User();
          updateAuthor.setId(author.getId());
          updateAuthor.setMyPublish(author.getMyPublish() - 1);
          userMapper.updateById(updateAuthor);
        }
      }

      return true;
    } catch (Exception e) {
      log.error("处理举报失败", e);
      throw new RuntimeException("处理举报失败: " + e.getMessage());
    }
  }

  @Override
  public List<GetPostListVO> getUserCollectionList(Integer userId) {
    try {
      // 1. 参数校验
      if (userId == null || userId <= 0) {
        throw new IllegalArgumentException("用户ID不合法");
      }

      // 2. 查询用户收藏的帖子ID列表
      QueryWrapper<PostCollect> collectWrapper = new QueryWrapper<>();
      collectWrapper.eq("userId", userId)
          .eq("status", 1)
          .orderByDesc("createTime");
      List<PostCollect> collectList = postCollectMapper.selectList(collectWrapper);

      if (collectList.isEmpty()) {
        return new ArrayList<>();
      }

      // 3. 获取所有收藏的帖子ID
      List<Integer> postIds = collectList.stream()
          .map(PostCollect::getPostId)
          .collect(Collectors.toList());

      // 4. 批量查询帖子信息
      QueryWrapper<Post> postWrapper = new QueryWrapper<>();
      postWrapper.in("id", postIds)
          .eq("postStatus", 3) // 只查询已发布的帖子
          .orderByDesc("createTime");
      List<Post> posts = postMapper.selectList(postWrapper);

      // 5. 转换为VO
      return convertToPostVOs(posts);
    } catch (Exception e) {
      log.error("获取用户收藏列表失败", e);
      throw new RuntimeException("获取用户收藏列表失败: " + e.getMessage());
    }
  }

  @Override
  public List<GetPostListVO> getUserPublishList(Integer userId) {
    try {
      // 1. 参数校验
      if (userId == null || userId <= 0) {
        throw new IllegalArgumentException("用户ID不合法");
      }

      // 2. 查询用户发布的帖子
      QueryWrapper<Post> postWrapper = new QueryWrapper<>();
      postWrapper.eq("authorId", userId)
          .eq("postStatus", 3) // 只查询已发布的帖子
          .orderByDesc("createTime");
      List<Post> posts = postMapper.selectList(postWrapper);

      if (posts.isEmpty()) {
        return new ArrayList<>();
      }

      // 3. 转换为VO
      return convertToPostVOs(posts);
    } catch (Exception e) {
      log.error("获取用户发布列表失败", e);
      throw new RuntimeException("获取用户发布列表失败: " + e.getMessage());
    }
  }

  @Override
  public List<GetPostListVO> getUserLikeList(Integer userId) {
    try {
      // 1. 参数校验
      if (userId == null || userId <= 0) {
        throw new IllegalArgumentException("用户ID不合法");
      }

      // 2. 查询用户点赞的帖子ID列表
      QueryWrapper<PostLike> likeWrapper = new QueryWrapper<>();
      likeWrapper.eq("userId", userId)
          .eq("status", 1)
          .orderByDesc("createTime");
      List<PostLike> likeList = postLikeMapper.selectList(likeWrapper);

      if (likeList.isEmpty()) {
        return new ArrayList<>();
      }

      // 3. 获取所有点赞的帖子ID
      List<Integer> postIds = likeList.stream()
          .map(PostLike::getPostId)
          .collect(Collectors.toList());

      // 4. 批量查询帖子信息
      QueryWrapper<Post> postWrapper = new QueryWrapper<>();
      postWrapper.in("id", postIds)
          .eq("postStatus", 3) // 只查询已发布的帖子
          .orderByDesc("createTime");
      List<Post> posts = postMapper.selectList(postWrapper);

      // 5. 转换为VO
      return convertToPostVOs(posts);
    } catch (Exception e) {
      log.error("获取用户点赞列表失败", e);
      throw new RuntimeException("获取用户点赞列表失败: " + e.getMessage());
    }
  }

  @Override
  public List<GetPostListVO> getPendingPosts() {
    try {
      // 1. 查询所有待审核的帖子
      List<Post> pendingPosts = this.list(
          new QueryWrapper<Post>()
              .eq("postStatus", 1) // 只查询待审核的帖子
              .orderByDesc("createTime") // 按创建时间降序
      );

      if (pendingPosts.isEmpty()) {
        return new ArrayList<>();
      }

      // 2. 转换为VO
      return convertToPostVOs(pendingPosts);
    } catch (Exception e) {
      log.error("获取待审核帖子列表失败", e);
      throw new RuntimeException("获取待审核帖子列表失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public boolean approvePost(Integer postId, Integer adminId) {
    try {
      // 1. 参数校验
      if (postId == null || postId <= 0) {
        throw new IllegalArgumentException("帖子ID不合法");
      }
      if (adminId == null || adminId <= 0) {
        throw new IllegalArgumentException("管理员ID不合法");
      }

      // 2. 查询帖子信息
      Post post = this.getById(postId);
      if (post == null) {
        throw new IllegalArgumentException("帖子不存在");
      }

      // 3. 检查帖子状态
      if (post.getPostStatus() != 1) {
        throw new IllegalArgumentException("只能审核待审核状态的帖子");
      }

      // 4. 更新帖子状态为已发布
      Post updatePost = new Post();
      updatePost.setId(postId);
      updatePost.setPostStatus(3); // 3表示已发布
      updatePost.setUpdateTime(new Date());
      boolean success = this.updateById(updatePost);

      if (success) {
        // 5. 给作者发送消息通知
        User author = userMapper.selectById(post.getAuthorId());
        if (author != null) {
          // 构建消息内容
          String messageContent = String.format(
              "您的帖子《%s》已通过审核，现已发布。",
              post.getTitle() != null && !post.getTitle().isEmpty() ? post.getTitle() : "无标题");

          // 创建消息DTO
          SendMessageDTO messageDTO = new SendMessageDTO();
          messageDTO.setReceiverId(post.getAuthorId());
          messageDTO.setContent(messageContent);
          messageDTO.setMessageType(1); // 系统消息类型

          // 发送消息
          messageService.sendMessage(adminId, messageDTO);
        }
      }

      return success;
    } catch (Exception e) {
      log.error("通过帖子审核失败", e);
      throw new RuntimeException("通过帖子审核失败: " + e.getMessage());
    }
  }

  @Override
  @Transactional
  public boolean rejectPost(Integer postId, Integer adminId, String reason) {
    try {
      // 1. 参数校验
      if (postId == null || postId <= 0) {
        throw new IllegalArgumentException("帖子ID不合法");
      }
      if (adminId == null || adminId <= 0) {
        throw new IllegalArgumentException("管理员ID不合法");
      }
      if (reason == null || reason.trim().isEmpty()) {
        throw new IllegalArgumentException("拒绝原因不能为空");
      }

      // 2. 查询帖子信息
      Post post = this.getById(postId);
      if (post == null) {
        throw new IllegalArgumentException("帖子不存在");
      }

      // 3. 检查帖子状态
      if (post.getPostStatus() != 1) {
        throw new IllegalArgumentException("只能审核待审核状态的帖子");
      }

      // 4. 更新帖子状态为已拒绝
      Post updatePost = new Post();
      updatePost.setId(postId);
      updatePost.setPostStatus(2); // 2表示已拒绝/已删除
      updatePost.setUpdateTime(new Date());
      boolean success = this.updateById(updatePost);

      if (success) {
        // 5. 给作者发送消息通知
        User author = userMapper.selectById(post.getAuthorId());
        if (author != null) {
          // 构建消息内容
          String messageContent = String.format(
              "您的帖子《%s》未通过审核。原因：%s",
              post.getTitle() != null && !post.getTitle().isEmpty() ? post.getTitle() : "无标题",
              reason.trim());

          // 创建消息DTO
          SendMessageDTO messageDTO = new SendMessageDTO();
          messageDTO.setReceiverId(post.getAuthorId());
          messageDTO.setContent(messageContent);
          messageDTO.setMessageType(1); // 系统消息类型

          // 发送消息
          messageService.sendMessage(adminId, messageDTO);

          // 6. 更新作者的发帖数
          if (author.getMyPublish() > 0) {
            User updateAuthor = new User();
            updateAuthor.setId(author.getId());
            updateAuthor.setMyPublish(author.getMyPublish() - 1);
            userMapper.updateById(updateAuthor);
          }
        }
      }

      return success;
    } catch (Exception e) {
      log.error("拒绝帖子审核失败", e);
      throw new RuntimeException("拒绝帖子审核失败: " + e.getMessage());
    }
  }

  private List<GetPostListVO> convertToPostVOs(List<Post> posts) {
    if (posts == null || posts.isEmpty()) {
      return Collections.emptyList();
    }
    // 1. 获取所有作者ID
    Set<Integer> authorIds = posts.stream()
        .map(Post::getAuthorId)
        .collect(Collectors.toSet());

    // 2. 批量查询作者信息
    Map<Integer, User> userMap = userMapper.selectBatchIds(authorIds)
        .stream()
        .collect(Collectors.toMap(User::getId, user -> user));

    // 3. 转换为VO对象
    return posts.stream().map(post -> {
      User author = userMap.get(post.getAuthorId());
      String authorName = author != null ? author.getUsername() : "未知用户";
      String authorAvatar = author != null ? author.getAvatar() : "";

      GetPostListVO postVO = GetPostListVO.builder()
          .id(post.getId())
          .authorId(post.getAuthorId())
          .authorName(post.getIsAnonymous() == 1 ? "匿名用户" : authorName)
          .authorAvatar(post.getIsAnonymous() == 1 ? "" : authorAvatar)
          .title(post.getTitle())
          .content(post.getContent())
          .image1(post.getImage1())
          .image2(post.getImage2())
          .image3(post.getImage3())
          .image4(post.getImage4())
          .image5(post.getImage5())
          .image6(post.getImage6())
          .image7(post.getImage7())
          .image8(post.getImage8())
          .image9(post.getImage9())
          .type(post.getType())
          .isAnonymous(post.getIsAnonymous())
          .createTime(post.getCreateTime())
          .updateTime(post.getUpdateTime())
          .viewsCount(post.getViewsCount())
          .commentsCount(post.getCommentsCount())
          .likesCount(post.getLikesCount())
          .collectsCount(post.getCollectsCount())
          .build();

      // 处理 tags
      if (post.getTags() != null && !post.getTags().isEmpty()) {
        try {
          List<String> tagsList = objectMapper.readValue(post.getTags(), new TypeReference<List<String>>() {
          });
          postVO.setTags(tagsList);
        } catch (JsonProcessingException e) {
          log.error("反序列化帖子列表标签失败, postId: {}", post.getId(), e);
          postVO.setTags(Collections.emptyList()); // 出错时返回空列表
        }
      } else {
        postVO.setTags(Collections.emptyList());
      }

      return postVO;
    }).collect(Collectors.toList());
  }

  @Override
  @Transactional
  public PostHeatVO increasePostHeat(IncreasePostHeatDTO increasePostHeatDTO) {
    // 1. 查询用户信息
    User user = userMapper.selectById(increasePostHeatDTO.getUserId());
    if (user == null) {
      throw new IllegalArgumentException("用户不存在");
    }

    // 2. 检查用户货币是否足够
    Integer currentCoins = user.getMyCoins() != null ? user.getMyCoins() : 0;
    if (currentCoins < increasePostHeatDTO.getCostCoins()) {
      throw new IllegalArgumentException("货币余额不足，当前余额：" + currentCoins + "，需要：" + increasePostHeatDTO.getCostCoins());
    }

    // 3. 查询帖子信息
    Post post = postMapper.selectById(increasePostHeatDTO.getPostId());
    if (post == null) {
      throw new IllegalArgumentException("帖子不存在");
    }
    if (!Integer.valueOf(3).equals(post.getPostStatus())) {
      throw new IllegalArgumentException("只能对已发布的帖子增加热度");
    }

    // 4. 记录操作前的热度值
    Integer beforeHeat = post.getHeatCount() != null ? post.getHeatCount() : 0;

    try {
      // 5. 扣除用户货币
      Integer newCoins = currentCoins - increasePostHeatDTO.getCostCoins();
      User updateUser = new User();
      updateUser.setId(increasePostHeatDTO.getUserId());
      updateUser.setMyCoins(newCoins);
      updateUser.setUpdateTime(new Date());
      
      int userUpdateResult = userMapper.updateById(updateUser);
      if (userUpdateResult <= 0) {
        throw new RuntimeException("扣除用户货币失败");
      }

      // 6. 增加帖子热度
      Integer afterHeat = beforeHeat + increasePostHeatDTO.getHeatValue();
      Post updatePost = new Post();
      updatePost.setId(increasePostHeatDTO.getPostId());
      updatePost.setHeatCount(afterHeat);
      updatePost.setUpdateTime(new Date());
      
      int postUpdateResult = postMapper.updateById(updatePost);
      if (postUpdateResult <= 0) {
        throw new RuntimeException("增加帖子热度失败");
      }

      // 7. 构建返回结果
      return PostHeatVO.builder()
          .postId(increasePostHeatDTO.getPostId())
          .beforeHeat(beforeHeat)
          .afterHeat(afterHeat)
          .costCoins(increasePostHeatDTO.getCostCoins())
          .remainingCoins(newCoins)
          .success(true)
          .build();

    } catch (Exception e) {
      log.error("增加帖子热度失败，用户ID：{}，帖子ID：{}，错误：{}", 
          increasePostHeatDTO.getUserId(), increasePostHeatDTO.getPostId(), e.getMessage());
      throw new RuntimeException("增加帖子热度失败：" + e.getMessage());
    }
  }

}
